/**
 * 
 */
package com.cea.papyrus.core.actions.profile;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Profile;

import com.cea.papyrus.core.actions.selectcopypaste.PapyrusSelectionAction;
import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.editpart.IUMLElementEditPart;
import com.cea.papyrus.core.utils.DiResourceSet;
import com.cea.papyrus.profile.definition.PapyrusDefinitionAnnotation;
import com.cea.papyrus.profile.definition.ProfileRedefinition;
import com.cea.papyrus.profile.ui.dialogs.ProfileDefinitionDialog;
import com.cea.papyrus.umlutils.PackageUtil;

/**
 * Action that calls the definition of a profile
 */
public class DefineProfileAction extends PapyrusSelectionAction {

	/** resource set that contains the resource where the modified Package is */
	protected final DiResourceSet diResourceSet;

	/** request key for the request associated to this action  */
	public final static String DEFINE_PROFILE_ACTION_REQUEST = DefineProfileAction.class.getName()+ "Request";

	/** ID of  this action */
	public final static String DEFINE_PROFILE_ACTION_ID = DefineProfileAction.class.getName()+ "ID";


	/**
	 * Creates a new DefineProfileAction
	 * @param part that part which contains the selection
	 */
	public DefineProfileAction(IWorkbenchPart part) {
		super(part);
		ModelManager manager = (ModelManager)part.getAdapter(ModelManager.class);
		diResourceSet = manager.getDiResourceSet();

		setText("Define Profile");
		setId(DEFINE_PROFILE_ACTION_ID);
		setToolTipText("Generate the definition for this profile (required for profile application)");

		// icon for action
		// ImageDescriptor descriptor = PapyrusPlugin.getImageDescriptor(PapyrusPlugin.UML_ICONS_16x16+"Stereotype.gif");
		// setImageDescriptor(descriptor);
		// setHoverImageDescriptor(descriptor);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void run() {
		final Profile profileToDefine = getSelectedProfile();
		if(profileToDefine == null) {
			return;
		}
		defineProfile(profileToDefine);
	}

	/**
	 * Execution part of the action
	 * @param profileToDefine
	 */
	public void defineProfile(Profile profileToDefine) {
		// define profile
		ProfileDefinitionDialog dialog = new ProfileDefinitionDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), profileToDefine);
		if(Dialog.OK==dialog.open()) {
			PapyrusDefinitionAnnotation papyrusAnnotation = dialog.getPapyrusDefinitionAnnotation();
			ProfileRedefinition.verifyBaseProperty(profileToDefine);
			PackageUtil.defineProfiles(profileToDefine);
			ProfileRedefinition.redefineProfile(profileToDefine, papyrusAnnotation);
			ProfileRedefinition.cleanProfile(profileToDefine);
			//test if the profile is well built
			boolean validation= diResourceSet.validateFile();
			if (validation==false){
				//remove last definition
				PackageUtil.removeLastDefinition(profileToDefine);
				MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Error during profile definition", "the profile is not valid and can not be defined!");
			}
		}
	}


	/**
	 * {@inheritDoc}
	 */
	@Override
	protected boolean calculateEnabled() {
		// look the selection.
		// if one of the element is a package and is not an imported package, it is enabled
		return(getSelectedProfile()!=null);
	}

	/**
	 * returns the first selected profile in the collection of selected elements
	 * @return the first selected profile in the collection of selected elements
	 */
	protected Profile getSelectedProfile() {
		final List<Profile> profiles =getSelectedProfiles(true);
		return (profiles.size()>0) ? profiles.get(0) : null;
	}
	/**
	 * Returns the collection of selected packages 
	 * @param filterImports <code>true</code> if imported elements are counted as valid results
	 * @return the collection of selected packages 
	 */
	protected List<Profile> getSelectedProfiles(boolean filterImports) {
		List<Profile> selectedProfile = new ArrayList<Profile>();
		Iterator<Object> it = getSelectedObjects().iterator();
		while (it.hasNext()) {
			Object object =  it.next();
			if(object instanceof IUMLElementEditPart) {
				IUMLElementEditPart<Element> editPart = (IUMLElementEditPart<Element>)object;
				if(editPart.getUmlElement() instanceof Profile) {
					if(editPart.isElementImport()) {
						if(!filterImports) {
							selectedProfile.add((Profile)editPart.getUmlElement());
						}
					} else {
						selectedProfile.add((Profile)editPart.getUmlElement());
					}
				}
			}
		}
		return selectedProfile;
	}
}
